﻿using System.Collections.Concurrent;

namespace TrackSystem.IO.Formula
{
    /// <summary>
    /// 运算符类
    /// </summary>
    public class Operator
    {
        #region 属性定义
        /// <summary>
        /// 统一标识符
        /// </summary>
        public Guid Id;

        /// <summary>
        /// 操作数的数量
        /// </summary>
        public int OpNum;

        /// <summary>
        /// 运算符
        /// </summary>
        public string opChar { get; set; }

        /// <summary>
        /// 是否有前一个运算符
        /// </summary>
        public bool Pre { get; set; }

        /// <summary>
        /// 运算符类型
        /// </summary>
        public OperatorType Type { get; set; }
        #endregion

        #region 构造函数
        public Operator(string op, OperatorType ot, int num)
        {
            Type = ot;
            OpNum = num;
            Id = Guid.NewGuid();
            opChar = op;
            Pre = true; 
        }

        public Operator(KeywordDef opDef, bool pre = true)
        {
            Id = Guid.NewGuid();
            opChar = opDef.Keyword;
            Pre = pre;
            OpNum = 0;    
            Type = opDef.Level;
            OpNum = opDef.OpNum;
        }        
        #endregion

        ///// <summary>
        ///// 构造函数
        ///// </summary>
        ///// <param name="opType"></param>
        //public Operator(OperatorType opType)
        //{
        //    Type = opType;
        //    Pre = true;
        //    OpNum = 0;
        //}
        /// <summary>
        /// 运算优先级比较
        /// </summary>
        /// <param name="opType"></param>
        /// <returns></returns>
        public bool CompareTo(OperatorType opType)
        {
            return Level(Type) > Level(opType);
        }

        /// <summary>
        /// 返回运算优先级
        /// </summary>
        /// <param name="opType"></param>
        /// <returns></returns>
        private int Level(OperatorType opType)
        {
            int op = (int)opType;
            return op / 10;
        }

        ///// <summary>
        ///// 构造函数
        ///// </summary>
        ///// <param name="op"></param>
        ///// <param name="pre"></param>
        //public Operator(string op, bool pre = true)
        //{
        //    Id = Guid.NewGuid();
        //    opChar = op;
        //    Pre = pre;
        //    OpNum = 0;

        //    switch (op)
        //    {
        //        case "dist": Type = OperatorType.DIST; OpNum = 4; break;
        //        case "azim": Type = OperatorType.AZIM; OpNum = 4; break;
        //        case ":": Type = OperatorType.COLON; OpNum = 3; break;
        //        case "^": Type = OperatorType.POW; OpNum = 2; break;
        //        case "*": Type = OperatorType.MUL; OpNum = 2; break;
        //        case "/": Type = OperatorType.DIV; OpNum = 2; break;
        //        case "%": Type = OperatorType.MOD; OpNum = 2; break;
        //        case "+": Type = OperatorType.ADD; OpNum = 2; break;

        //        case "-": Type = OperatorType.SUB; OpNum = 2; break;
        //        case "<": Type = OperatorType.LT; OpNum = 2; break;
        //        case ">": Type = OperatorType.GT; OpNum = 2; break;
        //        case "<=": Type = OperatorType.LE; OpNum = 2; break;
        //        case ">=": Type = OperatorType.GE; OpNum = 2; break;

        //        case "&&": Type = OperatorType.AND; OpNum = 2; break;
        //        case "||": Type = OperatorType.OR; OpNum = 2; break;
        //        case "==": Type = OperatorType.ET; OpNum = 2; break;
        //        case "!=": Type = OperatorType.UT; OpNum = 2; break;

        //        case "ramp": Type = OperatorType.RAMP; OpNum = 2; break;
        //        case "angle": Type = OperatorType.ANGLE; OpNum = 2; break;
        //        case "filter": Type = OperatorType.FILTER; OpNum = 2; break;

        //        case ".": Type = OperatorType.FIX; OpNum = 1; break;
        //        case "?": Type = OperatorType.QUESTION; OpNum = 1; break;
        //        case "tan": Type = OperatorType.TAN; OpNum = 1; break;
        //        case "atan": Type = OperatorType.ATAN; OpNum = 1; break;
        //        case "sin": Type = OperatorType.SIN; OpNum = 1; break;

        //        case "asin": Type = OperatorType.ASIN; OpNum = 1; break;
        //        case "cos": Type = OperatorType.COS; OpNum = 1; break;
        //        case "acos": Type = OperatorType.ACOS; OpNum = 1; break;
        //        case "sqrt": Type = OperatorType.SQRT; OpNum = 1; break;
        //        case "lg": Type = OperatorType.LG; OpNum = 1; break;
        //        case "int": Type = OperatorType.INT; OpNum = 1; break;
        //        case "rand": Type = OperatorType.RAND; OpNum = 1; break;
        //        case "abs": Type = OperatorType.ABS; OpNum = 1; break;
        //        case "!": Type = OperatorType.NOT; OpNum = 1; break;

        //        case "@": Type = OperatorType.END; break;
        //        case "(": Type = OperatorType.LB; break;
        //        case ")": Type = OperatorType.RB; break;
        //    }
        //}


        /// <summary>
        /// 转变为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"{opChar} | {Type}）";
        }
    }
}
